home *** CD-ROM | disk | FTP | other *** search
/ PC Open 107 / PC Open 107 CD 1.bin / CD1 / INTERNET / EMAIL / pop file / setup.exe / $_1_ / BerkeleyDB.pm < prev    next >
Encoding:
Perl POD Document  |  2003-05-17  |  32.2 KB  |  1,560 lines

  1.  
  2. package BerkeleyDB;
  3.  
  4.  
  5. #     Copyright (c) 1997-2003 Paul Marquess. All rights reserved.
  6. #     This program is free software; you can redistribute it and/or
  7. #     modify it under the same terms as Perl itself.
  8. #
  9.  
  10. # The documentation for this module is at the bottom of this file,
  11. # after the line __END__.
  12.  
  13. BEGIN { require 5.004_04 }
  14.  
  15. use strict;
  16. use Carp;
  17. use vars qw($VERSION @ISA @EXPORT $AUTOLOAD
  18.         $use_XSLoader);
  19.  
  20. $VERSION = '0.22';
  21.  
  22. require Exporter;
  23. #require DynaLoader;
  24. require AutoLoader;
  25.  
  26. BEGIN {
  27.     $use_XSLoader = 1 ;
  28.     { local $SIG{__DIE__} ; eval { require XSLoader } ; }
  29.  
  30.     if ($@) {
  31.         $use_XSLoader = 0 ;
  32.         require DynaLoader;
  33.         @ISA = qw(DynaLoader);
  34.     }
  35. }
  36.  
  37. @ISA = qw(Exporter DynaLoader);
  38. # Items to export into callers namespace by default. Note: do not export
  39. # names by default without a very good reason. Use EXPORT_OK instead.
  40. # Do not simply export all your public functions/methods/constants.
  41.  
  42. # NOTE -- Do not add to @EXPORT directly. It is written by mkconsts
  43. @EXPORT = qw(
  44.     DB_AFTER
  45.     DB_AGGRESSIVE
  46.     DB_ALREADY_ABORTED
  47.     DB_APPEND
  48.     DB_APPLY_LOGREG
  49.     DB_APP_INIT
  50.     DB_ARCH_ABS
  51.     DB_ARCH_DATA
  52.     DB_ARCH_LOG
  53.     DB_AUTO_COMMIT
  54.     DB_BEFORE
  55.     DB_BROADCAST_EID
  56.     DB_BTREE
  57.     DB_BTREEMAGIC
  58.     DB_BTREEOLDVER
  59.     DB_BTREEVERSION
  60.     DB_CACHED_COUNTS
  61.     DB_CDB_ALLDB
  62.     DB_CHECKPOINT
  63.     DB_CHKSUM_SHA1
  64.     DB_CLIENT
  65.     DB_CL_WRITER
  66.     DB_COMMIT
  67.     DB_CONSUME
  68.     DB_CONSUME_WAIT
  69.     DB_CREATE
  70.     DB_CURLSN
  71.     DB_CURRENT
  72.     DB_CXX_NO_EXCEPTIONS
  73.     DB_DELETED
  74.     DB_DELIMITER
  75.     DB_DIRECT
  76.     DB_DIRECT_DB
  77.     DB_DIRECT_LOG
  78.     DB_DIRTY_READ
  79.     DB_DONOTINDEX
  80.     DB_DUP
  81.     DB_DUPCURSOR
  82.     DB_DUPSORT
  83.     DB_EID_BROADCAST
  84.     DB_EID_INVALID
  85.     DB_ENCRYPT
  86.     DB_ENCRYPT_AES
  87.     DB_ENV_APPINIT
  88.     DB_ENV_AUTO_COMMIT
  89.     DB_ENV_CDB
  90.     DB_ENV_CDB_ALLDB
  91.     DB_ENV_CREATE
  92.     DB_ENV_DBLOCAL
  93.     DB_ENV_DIRECT_DB
  94.     DB_ENV_DIRECT_LOG
  95.     DB_ENV_FATAL
  96.     DB_ENV_LOCKDOWN
  97.     DB_ENV_LOCKING
  98.     DB_ENV_LOGGING
  99.     DB_ENV_NOLOCKING
  100.     DB_ENV_NOMMAP
  101.     DB_ENV_NOPANIC
  102.     DB_ENV_OPEN_CALLED
  103.     DB_ENV_OVERWRITE
  104.     DB_ENV_PANIC_OK
  105.     DB_ENV_PRIVATE
  106.     DB_ENV_REGION_INIT
  107.     DB_ENV_REP_CLIENT
  108.     DB_ENV_REP_LOGSONLY
  109.     DB_ENV_REP_MASTER
  110.     DB_ENV_RPCCLIENT
  111.     DB_ENV_RPCCLIENT_GIVEN
  112.     DB_ENV_STANDALONE
  113.     DB_ENV_SYSTEM_MEM
  114.     DB_ENV_THREAD
  115.     DB_ENV_TXN
  116.     DB_ENV_TXN_NOSYNC
  117.     DB_ENV_TXN_WRITE_NOSYNC
  118.     DB_ENV_USER_ALLOC
  119.     DB_ENV_YIELDCPU
  120.     DB_EXCL
  121.     DB_EXTENT
  122.     DB_FAST_STAT
  123.     DB_FCNTL_LOCKING
  124.     DB_FILE_ID_LEN
  125.     DB_FIRST
  126.     DB_FIXEDLEN
  127.     DB_FLUSH
  128.     DB_FORCE
  129.     DB_GETREC
  130.     DB_GET_BOTH
  131.     DB_GET_BOTHC
  132.     DB_GET_BOTH_RANGE
  133.     DB_GET_RECNO
  134.     DB_HANDLE_LOCK
  135.     DB_HASH
  136.     DB_HASHMAGIC
  137.     DB_HASHOLDVER
  138.     DB_HASHVERSION
  139.     DB_INCOMPLETE
  140.     DB_INIT_CDB
  141.     DB_INIT_LOCK
  142.     DB_INIT_LOG
  143.     DB_INIT_MPOOL
  144.     DB_INIT_TXN
  145.     DB_INVALID_EID
  146.     DB_JAVA_CALLBACK
  147.     DB_JOINENV
  148.     DB_JOIN_ITEM
  149.     DB_JOIN_NOSORT
  150.     DB_KEYEMPTY
  151.     DB_KEYEXIST
  152.     DB_KEYFIRST
  153.     DB_KEYLAST
  154.     DB_LAST
  155.     DB_LOCKDOWN
  156.     DB_LOCKMAGIC
  157.     DB_LOCKVERSION
  158.     DB_LOCK_CONFLICT
  159.     DB_LOCK_DEADLOCK
  160.     DB_LOCK_DEFAULT
  161.     DB_LOCK_DUMP
  162.     DB_LOCK_EXPIRE
  163.     DB_LOCK_FREE_LOCKER
  164.     DB_LOCK_GET
  165.     DB_LOCK_GET_TIMEOUT
  166.     DB_LOCK_INHERIT
  167.     DB_LOCK_MAXLOCKS
  168.     DB_LOCK_MINLOCKS
  169.     DB_LOCK_MINWRITE
  170.     DB_LOCK_NORUN
  171.     DB_LOCK_NOTEXIST
  172.     DB_LOCK_NOTGRANTED
  173.     DB_LOCK_NOTHELD
  174.     DB_LOCK_NOWAIT
  175.     DB_LOCK_OLDEST
  176.     DB_LOCK_PUT
  177.     DB_LOCK_PUT_ALL
  178.     DB_LOCK_PUT_OBJ
  179.     DB_LOCK_PUT_READ
  180.     DB_LOCK_RANDOM
  181.     DB_LOCK_RECORD
  182.     DB_LOCK_REMOVE
  183.     DB_LOCK_RIW_N
  184.     DB_LOCK_RW_N
  185.     DB_LOCK_SET_TIMEOUT
  186.     DB_LOCK_SWITCH
  187.     DB_LOCK_TIMEOUT
  188.     DB_LOCK_TRADE
  189.     DB_LOCK_UPGRADE
  190.     DB_LOCK_UPGRADE_WRITE
  191.     DB_LOCK_YOUNGEST
  192.     DB_LOGC_BUF_SIZE
  193.     DB_LOGFILEID_INVALID
  194.     DB_LOGMAGIC
  195.     DB_LOGOLDVER
  196.     DB_LOGVERSION
  197.     DB_LOG_DISK
  198.     DB_LOG_LOCKED
  199.     DB_LOG_SILENT_ERR
  200.     DB_MAX_PAGES
  201.     DB_MAX_RECORDS
  202.     DB_MPOOL_CLEAN
  203.     DB_MPOOL_CREATE
  204.     DB_MPOOL_DIRTY
  205.     DB_MPOOL_DISCARD
  206.     DB_MPOOL_EXTENT
  207.     DB_MPOOL_LAST
  208.     DB_MPOOL_NEW
  209.     DB_MPOOL_NEW_GROUP
  210.     DB_MPOOL_PRIVATE
  211.     DB_MULTIPLE
  212.     DB_MULTIPLE_KEY
  213.     DB_MUTEXDEBUG
  214.     DB_MUTEXLOCKS
  215.     DB_NEEDSPLIT
  216.     DB_NEXT
  217.     DB_NEXT_DUP
  218.     DB_NEXT_NODUP
  219.     DB_NOCOPY
  220.     DB_NODUPDATA
  221.     DB_NOLOCKING
  222.     DB_NOMMAP
  223.     DB_NOORDERCHK
  224.     DB_NOOVERWRITE
  225.     DB_NOPANIC
  226.     DB_NORECURSE
  227.     DB_NOSERVER
  228.     DB_NOSERVER_HOME
  229.     DB_NOSERVER_ID
  230.     DB_NOSYNC
  231.     DB_NOTFOUND
  232.     DB_ODDFILESIZE
  233.     DB_OK_BTREE
  234.     DB_OK_HASH
  235.     DB_OK_QUEUE
  236.     DB_OK_RECNO
  237.     DB_OLD_VERSION
  238.     DB_OPEN_CALLED
  239.     DB_OPFLAGS_MASK
  240.     DB_ORDERCHKONLY
  241.     DB_OVERWRITE
  242.     DB_PAD
  243.     DB_PAGEYIELD
  244.     DB_PAGE_LOCK
  245.     DB_PAGE_NOTFOUND
  246.     DB_PANIC_ENVIRONMENT
  247.     DB_PERMANENT
  248.     DB_POSITION
  249.     DB_POSITIONI
  250.     DB_PREV
  251.     DB_PREV_NODUP
  252.     DB_PRINTABLE
  253.     DB_PRIORITY_DEFAULT
  254.     DB_PRIORITY_HIGH
  255.     DB_PRIORITY_LOW
  256.     DB_PRIORITY_VERY_HIGH
  257.     DB_PRIORITY_VERY_LOW
  258.     DB_PRIVATE
  259.     DB_PR_HEADERS
  260.     DB_PR_PAGE
  261.     DB_PR_RECOVERYTEST
  262.     DB_QAMMAGIC
  263.     DB_QAMOLDVER
  264.     DB_QAMVERSION
  265.     DB_QUEUE
  266.     DB_RDONLY
  267.     DB_RDWRMASTER
  268.     DB_RECNO
  269.     DB_RECNUM
  270.     DB_RECORDCOUNT
  271.     DB_RECORD_LOCK
  272.     DB_RECOVER
  273.     DB_RECOVER_FATAL
  274.     DB_REGION_ANON
  275.     DB_REGION_INIT
  276.     DB_REGION_MAGIC
  277.     DB_REGION_NAME
  278.     DB_REGISTERED
  279.     DB_RENAMEMAGIC
  280.     DB_RENUMBER
  281.     DB_REP_CLIENT
  282.     DB_REP_DUPMASTER
  283.     DB_REP_HOLDELECTION
  284.     DB_REP_LOGSONLY
  285.     DB_REP_MASTER
  286.     DB_REP_NEWMASTER
  287.     DB_REP_NEWSITE
  288.     DB_REP_OUTDATED
  289.     DB_REP_PERMANENT
  290.     DB_REP_UNAVAIL
  291.     DB_REVSPLITOFF
  292.     DB_RMW
  293.     DB_RPC_SERVERPROG
  294.     DB_RPC_SERVERVERS
  295.     DB_RUNRECOVERY
  296.     DB_SALVAGE
  297.     DB_SECONDARY_BAD
  298.     DB_SEQUENTIAL
  299.     DB_SET
  300.     DB_SET_LOCK_TIMEOUT
  301.     DB_SET_RANGE
  302.     DB_SET_RECNO
  303.     DB_SET_TXN_NOW
  304.     DB_SET_TXN_TIMEOUT
  305.     DB_SNAPSHOT
  306.     DB_STAT_CLEAR
  307.     DB_SURPRISE_KID
  308.     DB_SWAPBYTES
  309.     DB_SYSTEM_MEM
  310.     DB_TEMPORARY
  311.     DB_TEST_ELECTINIT
  312.     DB_TEST_ELECTSEND
  313.     DB_TEST_ELECTVOTE1
  314.     DB_TEST_ELECTVOTE2
  315.     DB_TEST_ELECTWAIT1
  316.     DB_TEST_ELECTWAIT2
  317.     DB_TEST_POSTDESTROY
  318.     DB_TEST_POSTEXTDELETE
  319.     DB_TEST_POSTEXTOPEN
  320.     DB_TEST_POSTEXTUNLINK
  321.     DB_TEST_POSTLOG
  322.     DB_TEST_POSTLOGMETA
  323.     DB_TEST_POSTOPEN
  324.     DB_TEST_POSTRENAME
  325.     DB_TEST_POSTSYNC
  326.     DB_TEST_PREDESTROY
  327.     DB_TEST_PREEXTDELETE
  328.     DB_TEST_PREEXTOPEN
  329.     DB_TEST_PREEXTUNLINK
  330.     DB_TEST_PREOPEN
  331.     DB_TEST_PRERENAME
  332.     DB_TEST_SUBDB_LOCKS
  333.     DB_THREAD
  334.     DB_TIMEOUT
  335.     DB_TRUNCATE
  336.     DB_TXNMAGIC
  337.     DB_TXNVERSION
  338.     DB_TXN_ABORT
  339.     DB_TXN_APPLY
  340.     DB_TXN_BACKWARD_ALLOC
  341.     DB_TXN_BACKWARD_ROLL
  342.     DB_TXN_CKP
  343.     DB_TXN_FORWARD_ROLL
  344.     DB_TXN_GETPGNOS
  345.     DB_TXN_LOCK
  346.     DB_TXN_LOCK_2PL
  347.     DB_TXN_LOCK_MASK
  348.     DB_TXN_LOCK_OPTIMIST
  349.     DB_TXN_LOCK_OPTIMISTIC
  350.     DB_TXN_LOG_MASK
  351.     DB_TXN_LOG_REDO
  352.     DB_TXN_LOG_UNDO
  353.     DB_TXN_LOG_UNDOREDO
  354.     DB_TXN_NOSYNC
  355.     DB_TXN_NOWAIT
  356.     DB_TXN_OPENFILES
  357.     DB_TXN_POPENFILES
  358.     DB_TXN_PRINT
  359.     DB_TXN_REDO
  360.     DB_TXN_SYNC
  361.     DB_TXN_UNDO
  362.     DB_TXN_WRITE_NOSYNC
  363.     DB_UNKNOWN
  364.     DB_UNRESOLVED_CHILD
  365.     DB_UPDATE_SECONDARY
  366.     DB_UPGRADE
  367.     DB_USE_ENVIRON
  368.     DB_USE_ENVIRON_ROOT
  369.     DB_VERB_CHKPOINT
  370.     DB_VERB_DEADLOCK
  371.     DB_VERB_RECOVERY
  372.     DB_VERB_REPLICATION
  373.     DB_VERB_WAITSFOR
  374.     DB_VERIFY
  375.     DB_VERIFY_BAD
  376.     DB_VERIFY_FATAL
  377.     DB_VERSION_MAJOR
  378.     DB_VERSION_MINOR
  379.     DB_VERSION_PATCH
  380.     DB_VERSION_STRING
  381.     DB_VRFY_FLAGMASK
  382.     DB_WRITECURSOR
  383.     DB_WRITELOCK
  384.     DB_WRITEOPEN
  385.     DB_WRNOSYNC
  386.     DB_XA_CREATE
  387.     DB_XIDDATASIZE
  388.     DB_YIELDCPU
  389.     );
  390.  
  391. sub AUTOLOAD {
  392.     my($constname);
  393.     ($constname = $AUTOLOAD) =~ s/.*:://;
  394.     my ($error, $val) = constant($constname);
  395.     Carp::croak $error if $error;
  396.     no strict 'refs';
  397.     *{$AUTOLOAD} = sub { $val };
  398.     goto &{$AUTOLOAD};
  399. }         
  400.  
  401. #bootstrap BerkeleyDB $VERSION;
  402. if ($use_XSLoader)
  403.   { XSLoader::load("BerkeleyDB", $VERSION)}
  404. else
  405.   { bootstrap BerkeleyDB $VERSION }  
  406.  
  407. # Preloaded methods go here.
  408.  
  409.  
  410. sub ParseParameters($@)
  411. {
  412.     my ($default, @rest) = @_ ;
  413.     my (%got) = %$default ;
  414.     my (@Bad) ;
  415.     my ($key, $value) ;
  416.     my $sub = (caller(1))[3] ;
  417.     my %options = () ;
  418.     local ($Carp::CarpLevel) = 1 ;
  419.  
  420.     # allow the options to be passed as a hash reference or
  421.     # as the complete hash.
  422.     if (@rest == 1) {
  423.  
  424.         croak "$sub: parameter is not a reference to a hash"
  425.             if ref $rest[0] ne "HASH" ;
  426.  
  427.         %options = %{ $rest[0] } ;
  428.     }
  429.     elsif (@rest >= 2) {
  430.         %options = @rest ;
  431.     }
  432.  
  433.     while (($key, $value) = each %options)
  434.     {
  435.     $key =~ s/^-// ;
  436.  
  437.         if (exists $default->{$key})
  438.           { $got{$key} = $value }
  439.         else
  440.       { push (@Bad, $key) }
  441.     }
  442.     
  443.     if (@Bad) {
  444.         my ($bad) = join(", ", @Bad) ;
  445.         croak "unknown key value(s) @Bad" ;
  446.     }
  447.  
  448.     return \%got ;
  449. }
  450.  
  451. sub parseEncrypt
  452. {
  453.     my $got = shift ;
  454.  
  455.  
  456.     if (defined $got->{Encrypt}) {
  457.         croak("Encrypt parameter must be a hash reference")
  458.             if !ref $got->{Encrypt} || ref $got->{Encrypt} ne 'HASH' ;
  459.  
  460.     my %config = %{ $got->{Encrypt} } ;
  461.  
  462.         my $p = BerkeleyDB::ParseParameters({
  463.                     Password    => undef,
  464.                     Flags        => undef,
  465.                 }, %config);
  466.  
  467.         croak("Must specify Password and Flags with Encrypt parameter")
  468.         if ! (defined $p->{Password} && defined $p->{Flags});
  469.  
  470.         $got->{"Enc_Passwd"} = $p->{Password};
  471.         $got->{"Enc_Flags"} = $p->{Flags};
  472.     }
  473. }
  474.  
  475. use UNIVERSAL qw( isa ) ;
  476.  
  477. sub env_remove
  478. {
  479.     # Usage:
  480.     #
  481.     #    $env = new BerkeleyDB::Env
  482.     #            [ -Home        => $path, ]
  483.     #            [ -Config    => { name => value, name => value }
  484.     #            [ -Flags    => DB_INIT_LOCK| ]
  485.     #            ;
  486.  
  487.     my $got = BerkeleyDB::ParseParameters({
  488.                     Home        => undef,
  489.                     Flags         => 0,
  490.                     Config        => undef,
  491.                     }, @_) ;
  492.  
  493.     if (defined $got->{Config}) {
  494.         croak("Config parameter must be a hash reference")
  495.             if ! ref $got->{Config} eq 'HASH' ;
  496.  
  497.         @BerkeleyDB::a = () ;
  498.     my $k = "" ; my $v = "" ;
  499.     while (($k, $v) = each %{$got->{Config}}) {
  500.         push @BerkeleyDB::a, "$k\t$v" ;
  501.     }
  502.  
  503.         $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
  504.         if @BerkeleyDB::a ;
  505.     }
  506.  
  507.     return _env_remove($got) ;
  508. }
  509.  
  510. sub db_remove
  511. {
  512.     my $got = BerkeleyDB::ParseParameters(
  513.               {
  514.             Filename     => undef,
  515.             Subname        => undef,
  516.             Flags        => 0,
  517.             Env        => undef,
  518.               }, @_) ;
  519.  
  520.     croak("Must specify a filename")
  521.     if ! defined $got->{Filename} ;
  522.  
  523.     croak("Env not of type BerkeleyDB::Env")
  524.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  525.  
  526.     return _db_remove($got);
  527. }
  528.  
  529. sub db_rename
  530. {
  531.     my $got = BerkeleyDB::ParseParameters(
  532.               {
  533.             Filename     => undef,
  534.             Subname        => undef,
  535.             Newname        => undef,
  536.             Flags        => 0,
  537.             Env        => undef,
  538.               }, @_) ;
  539.  
  540.     croak("Env not of type BerkeleyDB::Env")
  541.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  542.  
  543.     croak("Must specify a filename")
  544.     if ! defined $got->{Filename} ;
  545.  
  546.     croak("Must specify a Subname")
  547.     if ! defined $got->{Subname} ;
  548.  
  549.     croak("Must specify a Newname")
  550.     if ! defined $got->{Newname} ;
  551.  
  552.     return _db_rename($got);
  553. }
  554.  
  555. sub db_verify
  556. {
  557.     my $got = BerkeleyDB::ParseParameters(
  558.               {
  559.             Filename     => undef,
  560.             Subname        => undef,
  561.             Outfile        => undef,
  562.             Flags        => 0,
  563.             Env        => undef,
  564.               }, @_) ;
  565.  
  566.     croak("Env not of type BerkeleyDB::Env")
  567.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  568.  
  569.     croak("Must specify a filename")
  570.     if ! defined $got->{Filename} ;
  571.  
  572.     return _db_verify($got);
  573. }
  574.  
  575. package BerkeleyDB::Env ;
  576.  
  577. use UNIVERSAL qw( isa ) ;
  578. use Carp ;
  579. use vars qw( %valid_config_keys ) ;
  580.  
  581. sub isaFilehandle
  582. {
  583.     my $fh = shift ;
  584.  
  585.     return ((isa($fh,'GLOB') or isa(\$fh,'GLOB')) and defined fileno($fh) )
  586.  
  587. }
  588.  
  589. %valid_config_keys = map { $_, 1 } qw( DB_DATA_DIR DB_LOG_DIR DB_TEMP_DIR
  590. DB_TMP_DIR ) ;
  591.  
  592. sub new
  593. {
  594.     # Usage:
  595.     #
  596.     #    $env = new BerkeleyDB::Env
  597.     #            [ -Home        => $path, ]
  598.     #            [ -Mode        => mode, ]
  599.     #            [ -Config    => { name => value, name => value }
  600.     #            [ -ErrFile       => filename, ]
  601.     #            [ -ErrPrefix     => "string", ]
  602.     #            [ -Flags    => DB_INIT_LOCK| ]
  603.     #            [ -Set_Flags    => $flags,]
  604.     #            [ -Cachesize    => number ]
  605.     #            [ -LockDetect    =>  ]
  606.     #            [ -Verbose    => boolean ]
  607.     #            [ -Encrypt    => { Password => string, Flags => value}
  608.     #
  609.     #            ;
  610.  
  611.     my $pkg = shift ;
  612.     my $got = BerkeleyDB::ParseParameters({
  613.                     Home        => undef,
  614.                     Server        => undef,
  615.                     Mode        => 0666,
  616.                     ErrFile      => undef,
  617.                     ErrPrefix     => undef,
  618.                     Flags         => 0,
  619.                     SetFlags         => 0,
  620.                     Cachesize         => 0,
  621.                     LockDetect         => 0,
  622.                     Verbose        => 0,
  623.                     Config        => undef,
  624.                     Encrypt        => undef,
  625.                     }, @_) ;
  626.  
  627.     if (defined $got->{ErrFile}) {
  628.         croak("ErrFile parameter must be a file name")
  629.             if ref $got->{ErrFile} ;
  630.     #if (!isaFilehandle($got->{ErrFile})) {
  631.     #    my $handle = new IO::File ">$got->{ErrFile}"
  632. #        or croak "Cannot open file $got->{ErrFile}: $!\n" ;
  633. #        $got->{ErrFile} = $handle ;
  634. #    }
  635.     }
  636.  
  637.     
  638.     my %config ;
  639.     if (defined $got->{Config}) {
  640.         croak("Config parameter must be a hash reference")
  641.             if ! ref $got->{Config} eq 'HASH' ;
  642.  
  643.     %config = %{ $got->{Config} } ;
  644.         @BerkeleyDB::a = () ;
  645.     my $k = "" ; my $v = "" ;
  646.     while (($k, $v) = each %config) {
  647.         if ($BerkeleyDB::db_version >= 3.1 && ! $valid_config_keys{$k} ){
  648.             $BerkeleyDB::Error = "illegal name-value pair: $k $v\n" ; 
  649.                 croak $BerkeleyDB::Error ;
  650.         }
  651.         push @BerkeleyDB::a, "$k\t$v" ;
  652.     }
  653.  
  654.         $got->{"Config"} = pack("p*", @BerkeleyDB::a, undef) 
  655.         if @BerkeleyDB::a ;
  656.     }
  657.  
  658.     BerkeleyDB::parseEncrypt($got);
  659.  
  660.     my ($addr) = _db_appinit($pkg, $got) ;
  661.     my $obj ;
  662.     $obj = bless [$addr] , $pkg if $addr ;
  663.     if ($obj && $BerkeleyDB::db_version >= 3.1 && keys %config) {
  664.     my ($k, $v);
  665.     while (($k, $v) = each %config) {
  666.         if ($k eq 'DB_DATA_DIR')
  667.           { $obj->set_data_dir($v) }
  668.         elsif ($k eq 'DB_LOG_DIR')
  669.           { $obj->set_lg_dir($v) }
  670.         elsif ($k eq 'DB_TEMP_DIR' || $k eq 'DB_TMP_DIR')
  671.           { $obj->set_tmp_dir($v) }
  672.         else {
  673.           $BerkeleyDB::Error = "illegal name-value pair: $k $v\n" ; 
  674.               croak $BerkeleyDB::Error 
  675.             }
  676.     }
  677.     }
  678.     return $obj ;
  679. }
  680.  
  681.  
  682. sub TxnMgr
  683. {
  684.     my $env = shift ;
  685.     my ($addr) = $env->_TxnMgr() ;
  686.     my $obj ;
  687.     $obj = bless [$addr, $env] , "BerkeleyDB::TxnMgr" if $addr ;
  688.     return $obj ;
  689. }
  690.  
  691. sub txn_begin
  692. {
  693.     my $env = shift ;
  694.     my ($addr) = $env->_txn_begin(@_) ;
  695.     my $obj ;
  696.     $obj = bless [$addr, $env] , "BerkeleyDB::Txn" if $addr ;
  697.     return $obj ;
  698. }
  699.  
  700. sub DESTROY
  701. {
  702.     my $self = shift ;
  703.     $self->_DESTROY() ;
  704. }
  705.  
  706. package BerkeleyDB::Hash ;
  707.  
  708. use vars qw(@ISA) ;
  709. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
  710. use UNIVERSAL qw( isa ) ;
  711. use Carp ;
  712.  
  713. sub new
  714. {
  715.     my $self = shift ;
  716.     my $got = BerkeleyDB::ParseParameters(
  717.               {
  718.             # Generic Stuff
  719.             Filename     => undef,
  720.             Subname        => undef,
  721.             #Flags        => BerkeleyDB::DB_CREATE(),
  722.             Flags        => 0,
  723.             Property    => 0,
  724.             Mode        => 0666,
  725.             Cachesize     => 0,
  726.             Lorder         => 0,
  727.             Pagesize     => 0,
  728.             Env        => undef,
  729.             #Tie         => undef,
  730.             Txn        => undef,
  731.             Encrypt        => undef,
  732.  
  733.             # Hash specific
  734.             Ffactor        => 0,
  735.             Nelem         => 0,
  736.             Hash         => undef,
  737.             DupCompare    => undef,
  738.  
  739.             # BerkeleyDB specific
  740.             ReadKey        => undef,
  741.             WriteKey    => undef,
  742.             ReadValue    => undef,
  743.             WriteValue    => undef,
  744.               }, @_) ;
  745.  
  746.     croak("Env not of type BerkeleyDB::Env")
  747.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  748.  
  749.     croak("Txn not of type BerkeleyDB::Txn")
  750.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  751.  
  752.     croak("-Tie needs a reference to a hash")
  753.     if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  754.  
  755.     BerkeleyDB::parseEncrypt($got);
  756.  
  757.     my ($addr) = _db_open_hash($self, $got);
  758.     my $obj ;
  759.     if ($addr) {
  760.         $obj = bless [$addr] , $self ;
  761.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  762.         $obj->Txn($got->{Txn}) 
  763.             if $got->{Txn} ;
  764.     }
  765.     return $obj ;
  766. }
  767.  
  768. *TIEHASH = \&new ;
  769.  
  770.  
  771. package BerkeleyDB::Btree ;
  772.  
  773. use vars qw(@ISA) ;
  774. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedHash ) ;
  775. use UNIVERSAL qw( isa ) ;
  776. use Carp ;
  777.  
  778. sub new
  779. {
  780.     my $self = shift ;
  781.     my $got = BerkeleyDB::ParseParameters(
  782.               {
  783.             # Generic Stuff
  784.             Filename     => undef,
  785.             Subname        => undef,
  786.             #Flags        => BerkeleyDB::DB_CREATE(),
  787.             Flags        => 0,
  788.             Property    => 0,
  789.             Mode        => 0666,
  790.             Cachesize     => 0,
  791.             Lorder         => 0,
  792.             Pagesize     => 0,
  793.             Env        => undef,
  794.             #Tie         => undef,
  795.             Txn        => undef,
  796.             Encrypt        => undef,
  797.  
  798.             # Btree specific
  799.             Minkey        => 0,
  800.             Compare        => undef,
  801.             DupCompare    => undef,
  802.             Prefix         => undef,
  803.               }, @_) ;
  804.  
  805.     croak("Env not of type BerkeleyDB::Env")
  806.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  807.  
  808.     croak("Txn not of type BerkeleyDB::Txn")
  809.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  810.  
  811.     croak("-Tie needs a reference to a hash")
  812.     if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  813.  
  814.     BerkeleyDB::parseEncrypt($got);
  815.  
  816.     my ($addr) = _db_open_btree($self, $got);
  817.     my $obj ;
  818.     if ($addr) {
  819.         $obj = bless [$addr] , $self ;
  820.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  821.         $obj->Txn($got->{Txn}) 
  822.             if $got->{Txn} ;
  823.     }
  824.     return $obj ;
  825. }
  826.  
  827. *BerkeleyDB::Btree::TIEHASH = \&BerkeleyDB::Btree::new ;
  828.  
  829.  
  830. package BerkeleyDB::Recno ;
  831.  
  832. use vars qw(@ISA) ;
  833. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  834. use UNIVERSAL qw( isa ) ;
  835. use Carp ;
  836.  
  837. sub new
  838. {
  839.     my $self = shift ;
  840.     my $got = BerkeleyDB::ParseParameters(
  841.               {
  842.             # Generic Stuff
  843.             Filename     => undef,
  844.             Subname        => undef,
  845.             #Flags        => BerkeleyDB::DB_CREATE(),
  846.             Flags        => 0,
  847.             Property    => 0,
  848.             Mode        => 0666,
  849.             Cachesize     => 0,
  850.             Lorder         => 0,
  851.             Pagesize     => 0,
  852.             Env        => undef,
  853.             #Tie         => undef,
  854.             Txn        => undef,
  855.             Encrypt        => undef,
  856.  
  857.             # Recno specific
  858.             Delim        => undef,
  859.             Len        => undef,
  860.             Pad        => undef,
  861.             Source         => undef,
  862.             ArrayBase     => 1, # lowest index in array
  863.               }, @_) ;
  864.  
  865.     croak("Env not of type BerkeleyDB::Env")
  866.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  867.  
  868.     croak("Txn not of type BerkeleyDB::Txn")
  869.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  870.  
  871.     croak("Tie needs a reference to an array")
  872.     if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  873.  
  874.     croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
  875.     if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;
  876.  
  877.  
  878.     BerkeleyDB::parseEncrypt($got);
  879.  
  880.     $got->{Fname} = $got->{Filename} if defined $got->{Filename} ;
  881.  
  882.     my ($addr) = _db_open_recno($self, $got);
  883.     my $obj ;
  884.     if ($addr) {
  885.         $obj = bless [$addr] , $self ;
  886.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  887.         $obj->Txn($got->{Txn}) 
  888.             if $got->{Txn} ;
  889.     }    
  890.     return $obj ;
  891. }
  892.  
  893. *BerkeleyDB::Recno::TIEARRAY = \&BerkeleyDB::Recno::new ;
  894. *BerkeleyDB::Recno::db_stat = \&BerkeleyDB::Btree::db_stat ;
  895.  
  896. package BerkeleyDB::Queue ;
  897.  
  898. use vars qw(@ISA) ;
  899. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  900. use UNIVERSAL qw( isa ) ;
  901. use Carp ;
  902.  
  903. sub new
  904. {
  905.     my $self = shift ;
  906.     my $got = BerkeleyDB::ParseParameters(
  907.               {
  908.             # Generic Stuff
  909.             Filename     => undef,
  910.             Subname        => undef,
  911.             #Flags        => BerkeleyDB::DB_CREATE(),
  912.             Flags        => 0,
  913.             Property    => 0,
  914.             Mode        => 0666,
  915.             Cachesize     => 0,
  916.             Lorder         => 0,
  917.             Pagesize     => 0,
  918.             Env        => undef,
  919.             #Tie         => undef,
  920.             Txn        => undef,
  921.             Encrypt        => undef,
  922.  
  923.             # Queue specific
  924.             Len        => undef,
  925.             Pad        => undef,
  926.             ArrayBase     => 1, # lowest index in array
  927.             ExtentSize      => undef,
  928.               }, @_) ;
  929.  
  930.     croak("Env not of type BerkeleyDB::Env")
  931.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  932.  
  933.     croak("Txn not of type BerkeleyDB::Txn")
  934.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  935.  
  936.     croak("Tie needs a reference to an array")
  937.     if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  938.  
  939.     croak("ArrayBase can only be 0 or 1, parsed $got->{ArrayBase}")
  940.     if $got->{ArrayBase} != 1 and $got->{ArrayBase} != 0 ;
  941.  
  942.     BerkeleyDB::parseEncrypt($got);
  943.  
  944.     $got->{Fname} = $got->{Filename} if defined $got->{Filename} ;
  945.  
  946.     my ($addr) = _db_open_queue($self, $got);
  947.     my $obj ;
  948.     if ($addr) {
  949.         $obj = bless [$addr] , $self ;
  950.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  951.         $obj->Txn($got->{Txn})
  952.             if $got->{Txn} ;
  953.     }    
  954.     return $obj ;
  955. }
  956.  
  957. *BerkeleyDB::Queue::TIEARRAY = \&BerkeleyDB::Queue::new ;
  958.  
  959. sub UNSHIFT
  960. {
  961.     my $self = shift;
  962.     croak "unshift is unsupported with Queue databases";
  963. }
  964.  
  965. ## package BerkeleyDB::Text ;
  966. ## 
  967. ## use vars qw(@ISA) ;
  968. ## @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  969. ## use UNIVERSAL qw( isa ) ;
  970. ## use Carp ;
  971. ## 
  972. ## sub new
  973. ## {
  974. ##     my $self = shift ;
  975. ##     my $got = BerkeleyDB::ParseParameters(
  976. ##               {
  977. ##             # Generic Stuff
  978. ##             Filename     => undef,
  979. ##             #Flags        => BerkeleyDB::DB_CREATE(),
  980. ##             Flags        => 0,
  981. ##             Property    => 0,
  982. ##             Mode        => 0666,
  983. ##             Cachesize     => 0,
  984. ##             Lorder         => 0,
  985. ##             Pagesize     => 0,
  986. ##             Env        => undef,
  987. ##             #Tie         => undef,
  988. ##             Txn        => undef,
  989. ## 
  990. ##             # Recno specific
  991. ##             Delim        => undef,
  992. ##             Len        => undef,
  993. ##             Pad        => undef,
  994. ##             Btree         => undef,
  995. ##               }, @_) ;
  996. ## 
  997. ##     croak("Env not of type BerkeleyDB::Env")
  998. ##     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  999. ## 
  1000. ##     croak("Txn not of type BerkeleyDB::Txn")
  1001. ##     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  1002. ## 
  1003. ##     croak("-Tie needs a reference to an array")
  1004. ##     if defined $got->{Tie} and $got->{Tie} !~ /ARRAY/ ;
  1005. ## 
  1006. ##     # rearange for recno
  1007. ##     $got->{Source} = $got->{Filename} if defined $got->{Filename} ;
  1008. ##     delete $got->{Filename} ;
  1009. ##     $got->{Fname} = $got->{Btree} if defined $got->{Btree} ;
  1010. ##     return BerkeleyDB::Recno::_db_open_recno($self, $got);
  1011. ## }
  1012. ## 
  1013. ## *BerkeleyDB::Text::TIEARRAY = \&BerkeleyDB::Text::new ;
  1014. ## *BerkeleyDB::Text::db_stat = \&BerkeleyDB::Btree::db_stat ;
  1015.  
  1016. package BerkeleyDB::Unknown ;
  1017.  
  1018. use vars qw(@ISA) ;
  1019. @ISA = qw( BerkeleyDB::Common BerkeleyDB::_tiedArray ) ;
  1020. use UNIVERSAL qw( isa ) ;
  1021. use Carp ;
  1022.  
  1023. sub new
  1024. {
  1025.     my $self = shift ;
  1026.     my $got = BerkeleyDB::ParseParameters(
  1027.               {
  1028.             # Generic Stuff
  1029.             Filename     => undef,
  1030.             Subname        => undef,
  1031.             #Flags        => BerkeleyDB::DB_CREATE(),
  1032.             Flags        => 0,
  1033.             Property    => 0,
  1034.             Mode        => 0666,
  1035.             Cachesize     => 0,
  1036.             Lorder         => 0,
  1037.             Pagesize     => 0,
  1038.             Env        => undef,
  1039.             #Tie         => undef,
  1040.             Txn        => undef,
  1041.             Encrypt        => undef,
  1042.  
  1043.               }, @_) ;
  1044.  
  1045.     croak("Env not of type BerkeleyDB::Env")
  1046.     if defined $got->{Env} and ! isa($got->{Env},'BerkeleyDB::Env');
  1047.  
  1048.     croak("Txn not of type BerkeleyDB::Txn")
  1049.     if defined $got->{Txn} and ! isa($got->{Txn},'BerkeleyDB::Txn');
  1050.  
  1051.     croak("-Tie needs a reference to a hash")
  1052.     if defined $got->{Tie} and $got->{Tie} !~ /HASH/ ;
  1053.  
  1054.     BerkeleyDB::parseEncrypt($got);
  1055.  
  1056.     my ($addr, $type) = _db_open_unknown($got);
  1057.     my $obj ;
  1058.     if ($addr) {
  1059.         $obj = bless [$addr], "BerkeleyDB::$type" ;
  1060.     push @{ $obj }, $got->{Env} if $got->{Env} ;
  1061.         $obj->Txn($got->{Txn})
  1062.             if $got->{Txn} ;
  1063.     }    
  1064.     return $obj ;
  1065. }
  1066.  
  1067.  
  1068. package BerkeleyDB::_tiedHash ;
  1069.  
  1070. use Carp ;
  1071.  
  1072. #sub TIEHASH  
  1073. #{ 
  1074. #    my $self = shift ;
  1075. #    my $db_object = shift ;
  1076. #
  1077. #print "Tiehash REF=[$self] [" . (ref $self) . "]\n" ;
  1078. #
  1079. #    return bless { Obj => $db_object}, $self ; 
  1080. #}
  1081.  
  1082. sub Tie
  1083. {
  1084.     # Usage:
  1085.     #
  1086.     #   $db->Tie \%hash ;
  1087.     #
  1088.  
  1089.     my $self = shift ;
  1090.  
  1091.     #print "Tie method REF=[$self] [" . (ref $self) . "]\n" ;
  1092.  
  1093.     croak("usage \$x->Tie \\%hash\n") unless @_ ;
  1094.     my $ref  = shift ; 
  1095.  
  1096.     croak("Tie needs a reference to a hash")
  1097.     if defined $ref and $ref !~ /HASH/ ;
  1098.  
  1099.     #tie %{ $ref }, ref($self), $self ; 
  1100.     tie %{ $ref }, "BerkeleyDB::_tiedHash", $self ; 
  1101.     return undef ;
  1102. }
  1103.  
  1104.  
  1105. sub TIEHASH  
  1106.     my $self = shift ;
  1107.     my $db_object = shift ;
  1108.     #return bless $db_object, 'BerkeleyDB::Common' ; 
  1109.     return $db_object ;
  1110. }
  1111.  
  1112. sub STORE
  1113. {
  1114.     my $self = shift ;
  1115.     my $key  = shift ;
  1116.     my $value = shift ;
  1117.  
  1118.     $self->db_put($key, $value) ;
  1119. }
  1120.  
  1121. sub FETCH
  1122. {
  1123.     my $self = shift ;
  1124.     my $key  = shift ;
  1125.     my $value = undef ;
  1126.     $self->db_get($key, $value) ;
  1127.  
  1128.     return $value ;
  1129. }
  1130.  
  1131. sub EXISTS
  1132. {
  1133.     my $self = shift ;
  1134.     my $key  = shift ;
  1135.     my $value = undef ;
  1136.     $self->db_get($key, $value) == 0 ;
  1137. }
  1138.  
  1139. sub DELETE
  1140. {
  1141.     my $self = shift ;
  1142.     my $key  = shift ;
  1143.     $self->db_del($key) ;
  1144. }
  1145.  
  1146. sub CLEAR
  1147. {
  1148.     my $self = shift ;
  1149.     my ($key, $value) = (0, 0) ;
  1150.     my $cursor = $self->_db_write_cursor() ;
  1151.     while ($cursor->c_get($key, $value, BerkeleyDB::DB_PREV()) == 0) 
  1152.     { $cursor->c_del() }
  1153. }
  1154.  
  1155. #sub DESTROY
  1156. #{
  1157. #    my $self = shift ;
  1158. #    print "BerkeleyDB::_tieHash::DESTROY\n" ;
  1159. #    $self->{Cursor}->c_close() if $self->{Cursor} ;
  1160. #}
  1161.  
  1162. package BerkeleyDB::_tiedArray ;
  1163.  
  1164. use Carp ;
  1165.  
  1166. sub Tie
  1167. {
  1168.     # Usage:
  1169.     #
  1170.     #   $db->Tie \@array ;
  1171.     #
  1172.  
  1173.     my $self = shift ;
  1174.  
  1175.     #print "Tie method REF=[$self] [" . (ref $self) . "]\n" ;
  1176.  
  1177.     croak("usage \$x->Tie \\%hash\n") unless @_ ;
  1178.     my $ref  = shift ; 
  1179.  
  1180.     croak("Tie needs a reference to an array")
  1181.     if defined $ref and $ref !~ /ARRAY/ ;
  1182.  
  1183.     #tie %{ $ref }, ref($self), $self ; 
  1184.     tie @{ $ref }, "BerkeleyDB::_tiedArray", $self ; 
  1185.     return undef ;
  1186. }
  1187.  
  1188.  
  1189. #sub TIEARRAY  
  1190. #{ 
  1191. #    my $self = shift ;
  1192. #    my $db_object = shift ;
  1193. #
  1194. #print "Tiearray REF=[$self] [" . (ref $self) . "]\n" ;
  1195. #
  1196. #    return bless { Obj => $db_object}, $self ; 
  1197. #}
  1198.  
  1199. sub TIEARRAY  
  1200.     my $self = shift ;
  1201.     my $db_object = shift ;
  1202.     #return bless $db_object, 'BerkeleyDB::Common' ; 
  1203.     return $db_object ;
  1204. }
  1205.  
  1206. sub STORE
  1207. {
  1208.     my $self = shift ;
  1209.     my $key  = shift ;
  1210.     my $value = shift ;
  1211.  
  1212.     $self->db_put($key, $value) ;
  1213. }
  1214.  
  1215. sub FETCH
  1216. {
  1217.     my $self = shift ;
  1218.     my $key  = shift ;
  1219.     my $value = undef ;
  1220.     $self->db_get($key, $value) ;
  1221.  
  1222.     return $value ;
  1223. }
  1224.  
  1225. *CLEAR =    \&BerkeleyDB::_tiedHash::CLEAR ;
  1226. *FIRSTKEY = \&BerkeleyDB::_tiedHash::FIRSTKEY ;
  1227. *NEXTKEY =  \&BerkeleyDB::_tiedHash::NEXTKEY ;
  1228.  
  1229. sub EXTEND {} # don't do anything with EXTEND
  1230.  
  1231.  
  1232. sub SHIFT
  1233. {
  1234.     my $self = shift;
  1235.     my ($key, $value) = (0, 0) ;
  1236.     my $cursor = $self->db_cursor() ;
  1237.     return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) != 0 ;
  1238.     return undef if $cursor->c_del() != 0 ;
  1239.  
  1240.     return $value ;
  1241. }
  1242.  
  1243.  
  1244. sub UNSHIFT
  1245. {
  1246.     my $self = shift;
  1247.     if (@_)
  1248.     {
  1249.         my ($key, $value) = (0, 0) ;
  1250.         my $cursor = $self->db_cursor() ;
  1251.         my $status = $cursor->c_get($key, $value, BerkeleyDB::DB_FIRST()) ;
  1252.         if ($status == 0)
  1253.         {
  1254.             foreach $value (reverse @_)
  1255.             {
  1256.             $key = 0 ;
  1257.             $cursor->c_put($key, $value, BerkeleyDB::DB_BEFORE()) ;
  1258.             }
  1259.         }
  1260.         elsif ($status == BerkeleyDB::DB_NOTFOUND())
  1261.         {
  1262.         $key = 0 ;
  1263.             foreach $value (@_)
  1264.             {
  1265.             $self->db_put($key++, $value) ;
  1266.             }
  1267.         }
  1268.     }
  1269. }
  1270.  
  1271. sub PUSH
  1272. {
  1273.     my $self = shift;
  1274.     if (@_)
  1275.     {
  1276.         my ($key, $value) = (-1, 0) ;
  1277.         my $cursor = $self->db_cursor() ;
  1278.         my $status = $cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) ;
  1279.         if ($status == 0 || $status == BerkeleyDB::DB_NOTFOUND())
  1280.     {
  1281.             $key = -1 if $status != 0 and $self->type != BerkeleyDB::DB_RECNO() ;
  1282.             foreach $value (@_)
  1283.         {
  1284.             ++ $key ;
  1285.             $status = $self->db_put($key, $value) ;
  1286.         }
  1287.     }
  1288.  
  1289. # can use this when DB_APPEND is fixed.
  1290. #        foreach $value (@_)
  1291. #        {
  1292. #        my $status = $cursor->c_put($key, $value, BerkeleyDB::DB_AFTER()) ;
  1293. #print "[$status]\n" ;
  1294. #        }
  1295.     }
  1296. }
  1297.  
  1298. sub POP
  1299. {
  1300.     my $self = shift;
  1301.     my ($key, $value) = (0, 0) ;
  1302.     my $cursor = $self->db_cursor() ;
  1303.     return undef if $cursor->c_get($key, $value, BerkeleyDB::DB_LAST()) != 0 ;
  1304.     return undef if $cursor->c_del() != 0 ;
  1305.  
  1306.     return $value ;
  1307. }
  1308.  
  1309. sub SPLICE
  1310. {
  1311.     my $self = shift;
  1312.     croak "SPLICE is not implemented yet" ;
  1313. }
  1314.  
  1315. *shift = \&SHIFT ;
  1316. *unshift = \&UNSHIFT ;
  1317. *push = \&PUSH ;
  1318. *pop = \&POP ;
  1319. *clear = \&CLEAR ;
  1320. *length = \&FETCHSIZE ;
  1321.  
  1322. sub STORESIZE
  1323. {
  1324.     croak "STORESIZE is not implemented yet" ;
  1325. #print "STORESIZE @_\n" ;
  1326. #    my $self = shift;
  1327. #    my $length = shift ;
  1328. #    my $current_length = $self->FETCHSIZE() ;
  1329. #print "length is $current_length\n";
  1330. #
  1331. #    if ($length < $current_length) {
  1332. #print "Make smaller $length < $current_length\n" ;
  1333. #        my $key ;
  1334. #        for ($key = $current_length - 1 ; $key >= $length ; -- $key)
  1335. #          { $self->db_del($key) }
  1336. #    }
  1337. #    elsif ($length > $current_length) {
  1338. #print "Make larger $length > $current_length\n" ;
  1339. #        $self->db_put($length-1, "") ;
  1340. #    }
  1341. #    else { print "stay the same\n" }
  1342.  
  1343. }
  1344.  
  1345.  
  1346.  
  1347. #sub DESTROY
  1348. #{
  1349. #    my $self = shift ;
  1350. #    print "BerkeleyDB::_tieArray::DESTROY\n" ;
  1351. #}
  1352.  
  1353.  
  1354. package BerkeleyDB::Common ;
  1355.  
  1356.  
  1357. use Carp ;
  1358.  
  1359. sub DESTROY
  1360. {
  1361.     my $self = shift ;
  1362.     $self->_DESTROY() ;
  1363. }
  1364.  
  1365. sub Txn
  1366. {
  1367.     my $self = shift ;
  1368.     my $txn  = shift ;
  1369.     #print "BerkeleyDB::Common::Txn db [$self] txn [$txn]\n" ;
  1370.     if ($txn) {
  1371.         $self->_Txn($txn) ;
  1372.         push @{ $txn }, $self ;
  1373.     }
  1374.     else {
  1375.         $self->_Txn() ;
  1376.     }
  1377.     #print "end BerkeleyDB::Common::Txn \n";
  1378. }
  1379.  
  1380.  
  1381. sub get_dup
  1382. {
  1383.     croak "Usage: \$db->get_dup(key [,flag])\n"
  1384.         unless @_ == 2 or @_ == 3 ;
  1385.  
  1386.     my $db        = shift ;
  1387.     my $key       = shift ;
  1388.     my $flag      = shift ;
  1389.     my $value       = 0 ;
  1390.     my $origkey   = $key ;
  1391.     my $wantarray = wantarray ;
  1392.     my %values      = () ;
  1393.     my @values    = () ;
  1394.     my $counter   = 0 ;
  1395.     my $status    = 0 ;
  1396.     my $cursor    = $db->db_cursor() ;
  1397.  
  1398.     # iterate through the database until either EOF ($status == 0)
  1399.     # or a different key is encountered ($key ne $origkey).
  1400.     for ($status = $cursor->c_get($key, $value, BerkeleyDB::DB_SET()) ;
  1401.      $status == 0 and $key eq $origkey ;
  1402.          $status = $cursor->c_get($key, $value, BerkeleyDB::DB_NEXT()) ) {
  1403.         # save the value or count number of matches
  1404.         if ($wantarray) {
  1405.         if ($flag)
  1406.                 { ++ $values{$value} }
  1407.         else
  1408.                 { push (@values, $value) }
  1409.     }
  1410.         else
  1411.             { ++ $counter }
  1412.      
  1413.     }
  1414.  
  1415.     return ($wantarray ? ($flag ? %values : @values) : $counter) ;
  1416. }
  1417.  
  1418. sub db_cursor
  1419. {
  1420.     my $db = shift ;
  1421.     my ($addr) = $db->_db_cursor(@_) ;
  1422.     my $obj ;
  1423.     $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
  1424.     return $obj ;
  1425. }
  1426.  
  1427. sub _db_write_cursor
  1428. {
  1429.     my $db = shift ;
  1430.     my ($addr) = $db->__db_write_cursor(@_) ;
  1431.     my $obj ;
  1432.     $obj = bless [$addr, $db] , "BerkeleyDB::Cursor" if $addr ;
  1433.     return $obj ;
  1434. }
  1435.  
  1436. sub db_join
  1437. {
  1438.     croak 'Usage: $db->BerkeleyDB::db_join([cursors], flags=0)'
  1439.     if @_ < 2 || @_ > 3 ;
  1440.     my $db = shift ;
  1441.     croak 'db_join: first parameter is not an array reference'
  1442.     if ! ref $_[0] || ref $_[0] ne 'ARRAY';
  1443.     my ($addr) = $db->_db_join(@_) ;
  1444.     my $obj ;
  1445.     $obj = bless [$addr, $db, $_[0]] , "BerkeleyDB::Cursor" if $addr ;
  1446.     return $obj ;
  1447. }
  1448.  
  1449. package BerkeleyDB::Cursor ;
  1450.  
  1451. sub c_close
  1452. {
  1453.     my $cursor = shift ;
  1454.     $cursor->[1] = "" ;
  1455.     return $cursor->_c_close() ;
  1456. }
  1457.  
  1458. sub c_dup
  1459. {
  1460.     my $cursor = shift ;
  1461.     my ($addr) = $cursor->_c_dup(@_) ;
  1462.     my $obj ;
  1463.     $obj = bless [$addr, $cursor->[1]] , "BerkeleyDB::Cursor" if $addr ;
  1464.     return $obj ;
  1465. }
  1466.  
  1467. sub DESTROY
  1468. {
  1469.     my $self = shift ;
  1470.     $self->_DESTROY() ;
  1471. }
  1472.  
  1473. package BerkeleyDB::TxnMgr ;
  1474.  
  1475. sub DESTROY
  1476. {
  1477.     my $self = shift ;
  1478.     $self->_DESTROY() ;
  1479. }
  1480.  
  1481. sub txn_begin
  1482. {
  1483.     my $txnmgr = shift ;
  1484.     my ($addr) = $txnmgr->_txn_begin(@_) ;
  1485.     my $obj ;
  1486.     $obj = bless [$addr, $txnmgr] , "BerkeleyDB::Txn" if $addr ;
  1487.     return $obj ;
  1488. }
  1489.  
  1490. package BerkeleyDB::Txn ;
  1491.  
  1492. sub Txn
  1493. {
  1494.     my $self = shift ;
  1495.     my $db ;
  1496.     # keep a reference to each db in the txn object
  1497.     foreach $db (@_) {
  1498.         $db->_Txn($self) ;
  1499.     push @{ $self}, $db ;
  1500.     }
  1501. }
  1502.  
  1503. sub txn_commit
  1504. {
  1505.     my $self = shift ;
  1506.     $self->disassociate() ;
  1507.     my $status = $self->_txn_commit() ;
  1508.     return $status ;
  1509. }
  1510.  
  1511. sub txn_abort
  1512. {
  1513.     my $self = shift ;
  1514.     $self->disassociate() ;
  1515.     my $status = $self->_txn_abort() ;
  1516.     return $status ;
  1517. }
  1518.  
  1519. sub disassociate
  1520. {
  1521.     my $self = shift ;
  1522.     my $db ;
  1523.     while ( @{ $self } > 2) {
  1524.         $db = pop @{ $self } ;
  1525.         $db->Txn() ;
  1526.     }
  1527.     #print "end disassociate\n" ;
  1528. }
  1529.  
  1530.  
  1531. sub DESTROY
  1532. {
  1533.     my $self = shift ;
  1534.  
  1535.     $self->disassociate() ;
  1536.     # first close the close the transaction
  1537.     $self->_DESTROY() ;
  1538. }
  1539.  
  1540. package BerkeleyDB::Term ;
  1541.  
  1542. END
  1543. {
  1544.     close_everything() ;
  1545. }
  1546.  
  1547.  
  1548. package BerkeleyDB ;
  1549.  
  1550.  
  1551.  
  1552. # Autoload methods go after =cut, and are processed by the autosplit program.
  1553.  
  1554. 1;
  1555. __END__
  1556.  
  1557.  
  1558.